package cz.mff.cuni.dpp.liboptions;

import java.util.HashSet;
import java.util.Set;

/**
 * Zakladní třída celé knihovny, pro parsování optionů potřebujete instanci a
 * nastavit jednotlivé Optiony, pak zavolat {@link #process(String[])}
 * 
 */
public class Options {

	private final Set<Option<?>> options = new HashSet<Option<?>>();

	public Options() {
	}

	public void addOptionDefinition(Option<?> option) throws OptionAliasConflictException {
		for (Option<?> originalOption : options) {
			Set<String> originalNames = originalOption.getNames();
			for (String newName : option.getNames()) {
				if (originalNames.contains(newName)) {
					throw new OptionAliasConflictException(originalOption, option, newName);
				}
			}
		}

		options.add(option);
	}

	public Result process(String[] args) {
		return OptionParser.parse(this, args);
	}

	public void printHelp() {
		for (Option<?> option : options) {
			// primarni jmeno tisknout nebudu
			// System.out.print(option.getPrimaryName());

			String placeholder = option.getValuePlaceholder();
			String separator = ""; // carka oddelujici volby

			// vytiskne aliasy, kratka volba
			for (String alias : option.getShortNames()) {
				System.out.print(separator + Option.SHORT_OPTION_PREFIX + alias);

				if (!placeholder.equals("")) {
					System.out.print(" " + placeholder);
				}

				separator = ", ";
			}

			// vytiskne aliasy, dlouha volba
			for (String alias : option.getLongNames()) {
				System.out.print(separator + Option.LONG_OPTION_PREFIX + alias);

				if (!placeholder.equals("")) {
					System.out.print("=" + placeholder);
				}

				separator = ", ";
			}
			System.out.println();

			// vytiskne popis
			System.out.println("\t\t" + option.getDescription());
		}
	}

	/**
	 * Vytiskne help, pro kazdou volbu jeden radek.
	 * 
	 * @param commandStart
	 *            - zacatek stringu pro volani prokazu, vetsinou bude obsahovat
	 *            jmeno programu, nebo napr<code>java -jar MyJar.jar</code>.
	 */
	public void printHelp(String commandStart) {
		System.out.println(commandStart);
		System.out.println();

		printHelp();
	}

	public Set<Option<?>> getOptions() {
		return new HashSet<Option<?>>(options);
	}
}
